﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDateTime>
#include "camera.h"

int index;
char dirpath[10];
PyObject* PFun1=NULL;
PyObject* PFun2=NULL;

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    initwindows();
    initPythonMoudle();
    connectsignal();
}


MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::initwindows()
{
    grabThread=new QThreadRead;
    procThread=new QThreadDeal;
    learnThread=new QThreadLearn;
    readLearnThread=new ReadForLearn;
    displayThread=new QThreadDisplay;
    img_dir = new QDir;


    QFont tabfont("Microsoft YaHei", 14, 75);
    ui->tabWidget->setFont(tabfont);

    ui->tabWidget->setTabText(0,QStringLiteral("学习模式"));
    ui->tabWidget->setTabText(1,QStringLiteral("分选模式"));

    ui->startButtom_2->setText(QStringLiteral("开始分选"));
    ui->stopButton_2->setText(QStringLiteral("停止"));

    ui->label_learn->setStyleSheet("border:2px solid red;");
    ui->label_sort->setStyleSheet("border:2px solid red");

    ui->label_learn->setStyleSheet("QLabel{background-color:rgb(0,0,0);}");
    ui->label_sort->setStyleSheet("QLabel{background-color:rgb(0,0,0);}");

    QFont font ( "Microsoft YaHei", 30, 75);
    ui->label_info->setFont(font);

    ui->label_info->setText(QStringLiteral("分选结果："));
}

void MainWindow::connectsignal()
{
    connect(ui->startButton_1,SIGNAL(clicked()),this,SLOT(startlearn()));
    connect(ui->stopgrabButton,SIGNAL(clicked()),this,SLOT(stoplearn()));
    connect(ui->startButtom_2,SIGNAL(clicked()),this,SLOT(startsort()));
    connect(ui->stopButton_2,SIGNAL(clicked()),this,SLOT(stopsort()));
    connect(ui->lightButton,SIGNAL(clicked()),this,SLOT(lightpress()));
    connect(ui->middleButton,SIGNAL(clicked()),this,SLOT(middlepress()));
    connect(ui->darkButton,SIGNAL(clicked()),this,SLOT(darkpress()));
    connect(ui->startgrabButton,SIGNAL(clicked()),this,SLOT(startgrab()));

    connect(procThread,SIGNAL(sendimage(cv::Mat)),this,SLOT(displayImage(cv::Mat)),Qt::BlockingQueuedConnection);
    connect(procThread,SIGNAL(sendRes(int)),this,SLOT(displayRes(int)),Qt::BlockingQueuedConnection);
    connect(learnThread,SIGNAL(learnCompelete()),this,SLOT(displayLearnSataus()),Qt::BlockingQueuedConnection);
    connect(displayThread,SIGNAL(sendimage2(cv::Mat)),this,SLOT(displayImageForLearn(cv::Mat)),Qt::BlockingQueuedConnection);
}

void MainWindow::startlearn()
{
    qDebug()<<"start learning";
    ui->leanstatuslabel->setText(QStringLiteral("学习中"));

    learnThread->start();
}

void MainWindow::startgrab()
{
    ui->infolabel->setStyleSheet("color:red;");
    ui->infolabel->setText(QStringLiteral("请选择输入的木板颜色"));

    readLearnThread->start();
    displayThread->start();
}

void MainWindow::stoplearn()
{
    qDebug()<<"stop learning";
    ui->colorlabel->setText("");

    //readLearnThread->exitThread();
    //readLearnThread->wait();
    readLearnThread->quit();
    closeCamera();
}

void MainWindow::startsort()
{
    qDebug()<<"start sorting";

    grabThread->start();
    procThread->start();
}

void MainWindow::stopsort()
{
    grabThread->exitThread();
    procThread->exitThread();
    grabThread->wait();
    procThread->wait();
    if(grabThread->isFinished()==false)
    {
        qDebug()<<"thread is running";
    }

    qDebug()<<"stop sorting";
}

void MainWindow::lightpress()
{
    ui->lightButton->setDown(true);
    ui->colorlabel->setText(QStringLiteral("浅色"));
    ui->infolabel->setText("");
    if(!img_dir->exists("./light"))
    {
        img_dir->mkdir("./light");
    }

    memset(dirpath,0,sizeof(dirpath));
    strcpy(dirpath,"./light/");
    index=0;
}

void MainWindow::middlepress()
{
    ui->middleButton->setDown(true);
    ui->colorlabel->setText(QStringLiteral("中色"));
    ui->infolabel->setText("");
    if(!img_dir->exists("./middle"))
    {
        img_dir->mkdir("./middle");
    }

    memset(dirpath,0,sizeof(dirpath));
    strcpy(dirpath,"./middle/");
    index=0;
}

void MainWindow::darkpress()
{
    ui->darkButton->setDown(true);
    ui->colorlabel->setText(QStringLiteral("深色"));
    ui->infolabel->setText("");
    if(!img_dir->exists("./dark"))
    {
        img_dir->mkdir("./dark");
    }

    memset(dirpath,0,sizeof(dirpath));
    strcpy(dirpath,"./dark/");
    index=0;
}

void MainWindow::displayImage(cv::Mat img)
{
    img=img.t();
    qDebug()<<"mian thread get data"<<img.cols;
    cv::cvtColor(img, img, CV_BGR2RGB);
    const unsigned char *pSrc = (const unsigned char*)img.data;

    QImage image(pSrc, img.cols, img.rows,img.step,QImage::Format_RGB888);

    //pix=QPixmap::fromImage(image.scaled(ui->label->width(),ui->label->height(),Qt::KeepAspectRatio));

    ui->label_sort->setPixmap(QPixmap::fromImage(image.scaled(ui->label_sort->width(),ui->label_sort->height(),Qt::KeepAspectRatio)));
    //std::cout<<mat;
    ui->label_sort->show();
}

void MainWindow::displayRes(int res)
{
    QFont font ( "Microsoft YaHei", 30, 75);
    ui->label_sortRes->setFont(font);

    switch(res)
    {
    case 0:
       ui->label_sortRes->setText(QStringLiteral("深色"));
        break;

    case 1:
        ui->label_sortRes->setText(QStringLiteral("中色"));
        break;

    case 2:
        ui->label_sortRes->setText(QStringLiteral("浅色"));
        break;

    default:
        break;
    }
}

void MainWindow::displayLearnSataus()
{
    ui->leanstatuslabel->setText(QStringLiteral("学习完成"));
    learnThread->quit();
    //delete learnThread;
}

void MainWindow::displayImageForLearn(cv::Mat img)
{
    img=img.t();
    qDebug()<<"mian thread get data"<<img.cols;
    cv::cvtColor(img, img, CV_BGR2RGB);
    const unsigned char *pSrc = (const unsigned char*)img.data;

    QImage image(pSrc, img.cols, img.rows,img.step,QImage::Format_RGB888);

    //pix=QPixmap::fromImage(image.scaled(ui->label->width(),ui->label->height(),Qt::KeepAspectRatio));

    ui->label_learn->setPixmap(QPixmap::fromImage(image.scaled(ui->label_sort->width(),ui->label_sort->height(),Qt::KeepAspectRatio)));
    //std::cout<<mat;
    ui->label_learn->show();
}

bool MainWindow::initPythonMoudle()
{
    Py_Initialize();                                                          //初始化python
    if (!Py_IsInitialized())
    {
        qDebug() << "Python init failed";
    }

    PyImport_ImportModule("sys");
    PyRun_SimpleString("import sys");                                        // 执行 python 中的短语句
    PyRun_SimpleString("sys.path.append('C:/Users/dk/Desktop/')");           //导入python模块路径（调用python文件的路径）

    PyObject *pModule;
    pModule = PyImport_ImportModule("woodboard");                            //导入Python文件名
    if (!pModule)
    {
        qDebug() << "import moudle failed";
        return false;
    }

    PyObject* pDict = PyModule_GetDict(pModule);                              //函数、类构建成字典
    if(!pDict)
    {
        qDebug()<<"import function failed";
        return false;
    }

    PyObject* pClass=PyDict_GetItemString(pDict,"TrainingData");             //获取python文件的类或函数
    if(!pClass)
    {
        qDebug()<<"get class failed";
        return false;
    }

    PyObject* pObject=PyInstanceMethod_New(pClass);                          //实例化类
    if(!pObject)
    {
        qDebug()<<"get init function failed";
        return false;
    }

    PFun1=PyObject_CallObject(pObject,NULL);                                 //调用__init__(self)
    if(!PFun1)
    {
        qDebug()<<"instance failed";
        return false;
    }

    pClass=NULL;
    pClass=PyDict_GetItemString(pDict,"Classification");
    if(!pClass)
    {
        qDebug()<<"get class failed";
        return false;
    }

    pObject=NULL;
    pObject=PyInstanceMethod_New(pClass);
    if(!pObject)
    {
        qDebug()<<"get init function failed";
        return false;
    }

    PFun2=PyObject_CallObject(pObject,NULL);
    if(!PFun2)
    {
        qDebug()<<"instance failed";
        return false;
    }

    //以下代码多个线程调用python使用，注意锁的拿取和释放，只能一个线程拿锁
    PyEval_InitThreads();                                                  // 初始化线程支持
    PyEval_ReleaseThread(PyThreadState_Get());            // 启动子线程前执行，释放PyEval_InitThreads获得的全局锁，否则子线程可能无法获取到全局锁
    return true;
}


